package com.ben.utils.pkg

import android.app.ActivityManager
import android.app.ActivityManager.RunningTaskInfo
import android.app.Application
import android.content.Context
import android.os.Process
import com.ben.utils.ext.launchGlobalIO
import com.ben.utils.ext.tryCatch
import com.ben.utils.log.Logger

/**
 * Author: bin.yang
 * Maintainer: bin.yang
 * Date: 2020/9/9
 * Copyright: 2020 Inc. All rights reserved.
 * Desc:
 */
object ProcessUtils {

    private const val TAG = "ProcessUtils"

    /**
     *  是否为主进程
     */
    fun isMainProcess(app: Application): Boolean {
        val pid = Process.myPid()
        val manager = app.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        for (process in manager.runningAppProcesses) {
            if (process.pid == pid) {
                Logger.d(TAG, "onCreate:packageName = ${app.packageName} , currentProcessName = ${process.processName}")
                if (process.processName == app.packageName) {
                    return true
                }
            }
        }
        return false
    }

    fun getCurrentProcessName(app: Application): String {
        val pid = Process.myPid()
        val manager = app.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        for (process in manager.runningAppProcesses) {
            if (process.pid == pid) {
                if (process.processName != null) {
                    return process.processName
                }
            }
        }
        return ""
    }

    /**
     * 停止正在运行的apk
     *
     * @param context
     * @param pkgName
     */
    fun stopRunningApp(context: Context, pkgName: String?) {
        tryCatch {
            val method = Class.forName("android.app.ActivityManager")
                .getMethod("forceStopPackage", String::class.java)
            val activityManager =
                context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
            method.invoke(activityManager, pkgName)
        }
    }

    /**
     *  停止指定包名的APP进程，排除顶层应用
     */
    fun stopPkgNameWithoutTopProcess(context: Context, pkgName: String?) {
        tryCatch {
            Logger.d(TAG, "stopPkgNameWithoutTopProcess: $pkgName")
            if (getTopProcessPkgName(context) != pkgName) {
                Logger.d(TAG, "stopPkgNameWithoutTopProcess kill: $pkgName")
                stopRunningApp(context, pkgName)
            }
        }
    }

    /**
     *  获取当前顶层应用包名
     */
    fun getTopProcessPkgName(context: Context): String {
        runCatching {
            return (
                (context.applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager)
                    .getRunningTasks(1)[0] as RunningTaskInfo
                ).topActivity?.packageName
                ?: ""
        }.exceptionOrNull()?.printStackTrace()
        return ""
    }

    /**
     *  获取顶层Activity类名
     */
    fun getTopActivityName(context: Context): String? {
        runCatching {
            return (
                (context.applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager)
                    .getRunningTasks(1)[0] as RunningTaskInfo
                ).topActivity?.className
        }
        return null
    }

    /**
     * 检查进程是否存活
     */
    fun checkProcess(context: Context, pkgName: String): Boolean {
        Logger.d(TAG, "checkProcess: $pkgName,needCheckProcess:")
        return (context.applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager)
            .runningAppProcesses.any {
                pkgName == it.processName
            }.apply {
                Logger.d(TAG, "checkProcess: $pkgName,alive：$this")
            }
    }

    /**
     * 停止正在运行的apk
     *
     * @param context
     * @param pkgName
     */
    fun forceStopPkg(context: Context, pkgName: String?) {
        launchGlobalIO {
            stopRunningApp(context, pkgName)
        }
    }

    /**
     * 获取pid对应的应用包名
     * @param pid
     * @return
     */
    fun getAppPkg(context: Context, pid: Int): String? {
        var processName = ""
        try {
            val activityManager =
                context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
            if (activityManager != null) {
                val list = activityManager.runningAppProcesses
                for (info in list) {
                    if (info.pid == pid) {
                        processName = info.processName
                        break
                    }
                }
            }
        } catch (throwable: Throwable) {
        }
        return processName
    }
}
